package utils.api.service;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import play.Logger;
import play.Play;

import com.google.gdata.client.authn.oauth.OAuthParameters;
import com.google.gdata.data.appsforyourdomain.AppsForYourDomainException;
import com.google.gdata.client.appsforyourdomain.UserService;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.data.appsforyourdomain.provisioning.UserEntry;
import com.google.gdata.data.appsforyourdomain.provisioning.UserFeed;

import exceptions.MarketConfigurationException;

public class MarketUserService {
	private static final String APPS_FEEDS_URL_BASE =
	      "https://apps-apis.google.com/a/feeds/";
	
	protected static final String SERVICE_VERSION = "2.0";
	
	protected String domainUrlBase;
	
	private String userMail;
	private String domain;
	private String appName;
	private String consumerKey;
	private String consumerSecret;
	
	private String oauth_requestor_param;
	private UserService userService;
	
	public MarketUserService(String userMail, String domain) {
		this.consumerKey = getConsumerKey();
		this.consumerSecret = getConsumerSecret();
		this.appName = getAppName();
		this.domain = domain;
		this.userMail = userMail;
		
		//this.oauth_requestor_param = "?xoauth_requestor_id=" + currentUser;
		this.domainUrlBase = APPS_FEEDS_URL_BASE + this.domain + "/";
		this.oauth_requestor_param = "xoauth_requestor_id=" + this.userMail;
		
		// Build the user service
		try {
			OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
			
			GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
			oauthParameters.setOAuthConsumerKey(this.consumerKey);
			oauthParameters.setOAuthConsumerSecret(this.consumerSecret);
			
			this.userService = new UserService(this.appName);
			userService.setOAuthCredentials(oauthParameters, signer);
		    userService.useSsl();
		} catch(Exception e) {
			e.printStackTrace(); // TODO
		}
	}
	
	public List<UserEntry> getUsersDomain() {
		try {
		    URL feedUrl = new URL("https://apps-apis.google.com/a/feeds/" + this.domain + "/user/2.0" + "?" + this.oauth_requestor_param); 
		    UserFeed userFeed = userService.getFeed(feedUrl, UserFeed.class);
		    return userFeed.getEntries();
	    } catch(Exception e) {
	    	Logger.error(e, "MarketUserService.getUsersDomain -> domain: " + this.domain);
	    }
	    
	    return new ArrayList<UserEntry>();
	}
	
	public UserEntry retrieveUser(String userName) {
		try {
			URL retrieveUrl = new URL(domainUrlBase + "user/" + SERVICE_VERSION + "/" + userName + "?" + this.oauth_requestor_param);
			return userService.getEntry(retrieveUrl, UserEntry.class);
		} catch(Exception e) {
			Logger.debug(e.getMessage());
			return null;
		}
	}
	
	public Boolean isAdmin(String userName) {
		Boolean admin = false;
		try {
		    URL feedUserUrl = new URL("https://apps-apis.google.com/a/feeds/" +  this.domain + "/user/2.0/" + userName + "?" + this.oauth_requestor_param);
		    UserEntry userEntry = userService.getEntry(feedUserUrl, UserEntry.class);
		    //UserEntry userEntry = resultFeed.getEntries().size() > 0 ? resultFeed.getEntries().get(0) : null;
		    
		    if(userEntry != null) admin = userEntry.getLogin().getAdmin();
		    
		} catch(Exception e) {
	    	Logger.error(e, "MarketUserService.isAdmin -> userName: " + userName);
	    }
		
		return admin;
	}
	
	protected String getAppName() {
		String appName =  Play.configuration.getProperty("market.appName", null);
		if(appName != null) return appName;
		else throw new MarketConfigurationException("market.appName");
	}
	
	protected String getConsumerKey() {
		String consumerKey = Play.configuration.getProperty("market.consumerKey", null);
		if(consumerKey != null) return consumerKey;
		else throw new MarketConfigurationException("market.consumerKey");
	}
	
	protected String getConsumerSecret() {
		String consumerSecret = Play.configuration.getProperty("market.consumerSecret", null);
		if(consumerSecret != null) return consumerSecret;
		else throw new MarketConfigurationException("market.consumerSecret");
	}
	
	public String getDomain() {
		return this.domain;
	}
}
